package com.xiyi.shouxin.utils;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.google.gson.Gson;
import com.xiyi.shouxin.conf.WXConfig;


// 微信工具类
@Component
public class WXUtil {

    @Autowired
    private RestTemplate clent;

    @Autowired
    private Logger logger;

    private Gson gson= new Gson();

    // 获取access_token响应封装
    public static class AccessTokenResponse {
        public String errCode;
        public String errMsg;

        public String accessToken;
        public String expiresIn;
        public String refreshToken;
        public String openId;
        public String scope;
    }

    // 获取access_token
    public AccessTokenResponse accessToken(String code) {
        Map<String, String> params = new HashMap<>();
        params.put("appid", WXConfig.getAppId());
        params.put("secret", WXConfig.getSecret());
        params.put("code", code);
        params.put("grant_type", "authorization_code");
        try {
            ResponseEntity<AccessTokenResponse> res = clent.getForEntity(WXConfig.getAccessTokenUrl(),
                    AccessTokenResponse.class, params);
            if (res.getStatusCode().equals(HttpStatus.OK)) {
                AccessTokenResponse body = res.getBody();
                return body;
            } else {
                logger.error("获取微信access_token失败，http状态码：{}，请求参数：{}", res.getStatusCode(), params.toString());
                return null;
            }
        } catch (Exception e) {
            logger.error("获取微信access_token失败，请求参数：{}", params.toString());
        }
        return null;
    }

    // 刷新access_token
    public AccessTokenResponse refreshToken(String refreshToken) {
        Map<String, String> params = new HashMap<>();
        params.put("appid", WXConfig.getAppId());
        params.put("refresh_token", refreshToken);
        params.put("grant_type", "refresh_token");
        try {
            ResponseEntity<AccessTokenResponse> res = clent.getForEntity(WXConfig.getRefreshTokenUrl(),
                    AccessTokenResponse.class, params);
            if (res.getStatusCode().equals(HttpStatus.OK)) {
                AccessTokenResponse body = res.getBody();
                return body;
            } else {
                logger.error("刷新微信access_token失败，http状态码：{}，请求参数：{}", res.getStatusCode(), params.toString());
                return null;
            }
        } catch (Exception e) {
            logger.error("刷新微信access_token失败，请求参数：{}", params.toString());
        }
        return null;
    }

    // 检验access_token
    public AccessTokenResponse checkToken(String accessToken, String openId) {
        Map<String, String> params = new HashMap<>();
        params.put("access_token", accessToken);
        params.put("openid", openId);
        try {
            ResponseEntity<AccessTokenResponse> res = clent.getForEntity(WXConfig.getCheckTokenUrl(),
                    AccessTokenResponse.class, params);
            if (res.getStatusCode().equals(HttpStatus.OK)) {
                AccessTokenResponse body = res.getBody();
                return body;
            } else {
                logger.error("检验微信access_token失败，http状态码：{}，请求参数：{}", res.getStatusCode(), params.toString());
                return null;
            }
        } catch (Exception e) {
            logger.error("检验微信access_token失败，请求参数：{}", params.toString());
        }
        return null;
    }

    // 获取用户个人信息响应封装
    public static class UserInfoResponse {
        public String errCode;
        public String errMsg;

        // 普通用户的标识，对当前开发者帐号唯一
        public String openId;
        // 普通用户昵称
        public String nickName;
        // 普通用户性别，1为男性，2为女性
        public String sex;
        // 通用户个人资料填写的省份
        public String province;
        // 普通用户个人资料填写的城市
        public String city;
        // 国家，如中国为CN
        public String country;
        // 用户头像，最后一个数值代表正方形头像大小（有0、46、64、96、132数值可选，0代表640*640正方形头像），用户没有头像时该项为空
        public String headImgurl;
        // 用户特权信息，json数组，如微信沃卡用户为（chinaunicom）
        public String privilege;
        // 针对一个微信开放平台帐号下的应用，同一用户的unionid是唯一的。
        public String unionId;
    }

    // 获取用户个人信息
    public UserInfoResponse userInfo(String accessToken, String openId) {
        Map<String, String> params = new HashMap<>();
        params.put("access_token", accessToken);
        params.put("openid", openId);
        try {
            ResponseEntity<UserInfoResponse> res = clent.getForEntity(WXConfig.getUserInfoUrl(),
                    UserInfoResponse.class, params);
            if (res.getStatusCode().equals(HttpStatus.OK)) {
                UserInfoResponse body = res.getBody();
                return body;
            } else {
                logger.error("获取微信用户个人信息失败，http状态码：{}，请求参数：{}", res.getStatusCode(), params.toString());
                return null;
            }
        } catch (Exception e) {
            logger.error("获取微信用户个人信息失败，请求参数：{}", params.toString());
        }
        return null;
    }

    public static class Code2SessionResponse {
        public int errcode;
        public String errmsg;

        public String session_key;//会话密钥
        public String unionid;//用户在开放平台的唯一标识符，若当前小程序已绑定到微信开放平台账号下会返回
        public String openid;//用户唯一标识
        public int expires_in;
    }


    // 小程序登录
    public Code2SessionResponse Code2Session(String js_code) {
        try {
            String query=WXConfig.getCode2Session();
            query=query+"?appid="+WXConfig.getAppId();
            query=query+"&secret="+WXConfig.getSecret();
            query=query+"&js_code="+js_code;
            query=query+"&grant_type=authorization_code";
            URI uri=new URI(query);
            ResponseEntity<String> res = clent.getForEntity(uri,String.class);
            if (res.getStatusCode().equals(HttpStatus.OK)) {
                String body = res.getBody();
                return gson.fromJson(body, Code2SessionResponse.class);
            } else {
                logger.error("小程序登录失败，http状态码：{}，请求参数：{}", res.getStatusCode(), query.toString());
                return null;
            }
        } catch (Exception e) {
            logger.error("小程序登录失败：", e);
        }
        return null;
    }


}
